
import sys
sys.path.append(r'code')
from backtest.ret_calc import Ret_calc
sys.path.append(r'code/frame')
from training.dl_frame_class.month_rolling.quant import Quant
from data_read.get_feature import Get_feature_data,  Get_npz_feature, Get_feature_data_many
from data_read.get_label import Get_npz_label, Get_label_data, Get_class_label
import os
import operator
import numpy as np
from multiprocessing import  Process
import itertools
import argparse
#basic
parser = argparse.ArgumentParser(description='ml_training structure')
parser.add_argument('--result_root', type=str,  default='dl_test', help='the root to save result')
parser.add_argument('--feature_root', type=str,  default=None, help='the root to read feature')
parser.add_argument('--label_root', type=str,  default=None, help='the root to read label')

#time
parser.add_argument('--time_param', type=dict,  default={"insample_beg": '2018-7',
                                                        "insample_end": '2020-7',
                                                        "outsample_beg": '2020-8',
                                                        "outsample_end": '2022-11',
                                                        }, help='time param for training')

#train_device
parser.add_argument('--use_gpu', type=bool, default=True, help='use gpu')
parser.add_argument('--gpu', type=int, default=0, help='gpu')
parser.add_argument('--use_multi_gpu', type=bool, default=False, help='use multiple gpus')
parser.add_argument('--devices', type=str, default='0,1,2,3', help='device ids of multile gpus')


#train_control
parser.add_argument('--model_type', type=str,  default='dl', help='the step of rolling train')
parser.add_argument('--early_stop', type=int,  default=10, help='the step of rolling train')
parser.add_argument('--rolling_step', type=int,  default=12, help='the step of rolling train')
parser.add_argument('--label_standard', type=str,  default=None, help='standard methord for feature processing')
parser.add_argument('--train_ratio', type=float,  default=0.8, help='the ratio to split train, eval and test')
parser.add_argument('--feature_list', type=list,  default=['high', 'low', 'close', 'vol', 'volume', 'oi'], help='feature name')
parser.add_argument('--varieties', type=list,  default=None, help='codes num')
parser.add_argument('--label_range', type=int,  default=10, help='the periods of thre sum of return')
parser.add_argument('--divide_vol', type=bool,  default=False, help='to decide that regression label is dividing vol')
parser.add_argument('--log_eval',  type=int,  default=5000, help='the step of log_eval')
parser.add_argument('--predict_save', type=bool,  default=True, help='weather saving predict result')
parser.add_argument('--finetune_month', type=int,  default=12, help='the step of rolling train')

#model
parser.add_argument('--pretrain_epoch', type=int,  default=1, help='the step of rolling train')
parser.add_argument('--finetune_epoch', type=int,  default=1, help='the step of rolling train')
parser.add_argument('--seq_len', type=int,  default=20, help='the step of rolling train')
parser.add_argument('--back_len', type=int,  default=0, help='the step of rolling train')
parser.add_argument('--horizon', type=int,  default=0, help='the step of rolling train')
parser.add_argument('--lr', type=float,  default=0.001, help='the step of rolling train')
parser.add_argument('--batch_size', type=int,  default=8, help='the step of rolling train')
args = parser.parse_args()

parser.add_argument('--backtest_time', type=dict,  default={"beg": '2021-7-28', "end": '2022-12-31', }, help='time param for backtest')
parser.add_argument('--cost_ratio', type=float,  default=0.001, help='the ratio of cost')
parser.add_argument('--money_init', type=float,  default=20000, help='the money of backtest')
parser.add_argument('--stop_loss', type=float,  default=-0.02, help='the ratio of stop loss')
parser.add_argument('--stop_ret', type=float,  default=0.15, help='the ratio of stop ret')
parser.add_argument('--hold_num', type=int,  default=5, help='the ratio of stop ret')
parser.add_argument('--open_thred', type=float,  default=0.04, help='the ratio of stop ret')
parser.add_argument('--label_ret', type=float,  default=0.04, help='the ratio of stop ret')

parser.add_argument('--stop_command', type=bool,  default=True, help='the ratio of stop ret')
parser.add_argument('--sub_command', type=bool,  default=True, help='the ratio of stop ret')
args = parser.parse_args()


args.feature_root = [r'data/cmodty/my_feature/feature_data']#'data/cmodty/my_feature/feature_data',r'data/cmodty/my_feature/feature_data_huangeven', r'data/cmodty/my_feature/feature_data_101'
args.label_root = r'data/stock_data/consentrate_daily_price'

lst_fea = []
for i in args.feature_root:
    lst_temp = os.listdir(i)
    lst_fea.extend(lst_temp)
args.feature_list = lst_fea  

args.result_root = r'result/frame/class/bce'
args.model_name = 'lightgbm'
args.result_root = os.path.join(args.result_root, str(args.label_range) ) #f'label_{args.label_range}'
if not os.path.exists(args.result_root):
    os.makedirs(args.result_root)

qb = Quant(args)

class Ml_quant():   
    
    def __init__(self, QuantBuider) -> None:
        self.qb = QuantBuider
        
    def creat_quant(self):
        feature, label, codes, times = self.qb.get_data(Get_feature_data_many, Get_class_label)
        self.qb.pre_finetune(codes,times,feature,label)
        

        
M = Ml_quant(qb)
M.creat_quant() 

from backtest.pos_make.pos_make_var import Pos_make_rank_thred_month_var, Pos_make_series_thred_month_var
from backtest.pos_make.pos_make import Pos_make_rank_thred_month, Pos_make_series_thred_month
from backtest.ret_calc import Ret_calc

def pos_main(args, pos_make_class = Pos_make_rank_thred_month):
    P = pos_make_class(args)
    P.pos_make()
    R = Ret_calc(args, P.buy_pos, P.sell_pos, P.hold_pos,  P.money_df, P.__class__.__name__)
    R.calc_ret()
    del P
    del R

lst = [Pos_make_rank_thred_month,Pos_make_series_thred_month,Pos_make_rank_thred_month_var,Pos_make_series_thred_month_var]
from joblib import Parallel, delayed
Parallel(n_jobs=16)(delayed(pos_main)(args,i) for i in lst)